//
//  UITableView.swift
//  Documentation
//
//  Created by Toj on 11/18/22.
//
//  UITableView
//

open class UITableView : UIScrollView, NSCoding, UIDataSourceTranslating {
    
    // 视图的样式
    open var style: UITableView.Style { get }
    
    // 数据源代理
    weak open var dataSource: UITableViewDataSource?
    
    // 交互代理
    weak open var delegate: UITableViewDelegate?
    
    @available(iOS 10.0, *)
    // 预加载代理
    weak open var prefetchDataSource: UITableViewDataSourcePrefetching?
    
    @available(iOS 15.0, *)
    // 属性默认开启, 会将点击的cell放置在最上方
    open var isPrefetchingEnabled: Bool
    
    
    @available(iOS 11.0, *)
    weak open var dragDelegate: UITableViewDragDelegate?
    
    @available(iOS 11.0, *)
    weak open var dropDelegate: UITableViewDropDelegate?
    
    // 默认是 UITableViewAutomaticDimension
    // 设置cell 高度
    open var rowHeight: CGFloat
    
    // 默认是 UITableViewAutomaticDimension
    // 设置section 视图的头标签高度
    open var sectionHeaderHeight: CGFloat
    
    // 默认是 UITableViewAutomaticDimension
    // 设置section 视图的尾标签高度
    open var sectionFooterHeight: CGFloat // default is UITableViewAutomaticDimension
    
    @available(iOS 7.0, *)
    open var estimatedRowHeight: CGFloat // default is UITableViewAutomaticDimension, set to 0 to disable
    
    @available(iOS 7.0, *)
    open var estimatedSectionHeaderHeight: CGFloat // default is UITableViewAutomaticDimension, set to 0 to disable
    
    @available(iOS 7.0, *)
    open var estimatedSectionFooterHeight: CGFloat // default is UITableViewAutomaticDimension, set to 0 to disable
    
    
    /// The height for filler rows added below the last row when there aren't enough rows to fill a plain style table view.
    /// Set 0 to disable filler rows entirely, use `UITableViewAutomaticDimension` for the default height.
    @available(iOS 15.0, *)
    open var fillerRowHeight: CGFloat
    
    
    /// Padding above each section header. The default value is `UITableViewAutomaticDimension`.
    @available(iOS 15.0, *)
    open var sectionHeaderTopPadding: CGFloat
    
    
    @available(iOS 7.0, *)
    open var separatorInset: UIEdgeInsets // allows customization of the frame of cell separators; see also the separatorInsetReference property. Use UITableViewAutomaticDimension for the automatic inset for that edge.
    
    @available(iOS 11.0, *)
    open var separatorInsetReference: UITableView.SeparatorInsetReference // Changes how custom separatorInset values are interpreted. The default value is UITableViewSeparatorInsetFromCellEdges
    
    // 背景视图将自动调整大小, 以跟踪表视图的大小.
    // 这将作为表视图的子视图放置在所有单元格和页眉/页脚后面.
    // Default对于某些设备可能是非空值. 只能写入
    open var backgroundView: UIView?
    
    
    @available(iOS 14.0, *)
    open var contextMenuInteraction: UIContextMenuInteraction? { get }
    
    
    // Info
    // 获取当前所有的组
    open var numberOfSections: Int { get }
    // 获取某个组有多少行
    open func numberOfRows(inSection section: Int) -> Int
    
    // 获取某个组的位置和大小, 包含页眉、页脚和所有行
    open func rect(forSection section: Int) -> CGRect
    
    // 获取某个组的头标签的位置和大小
    open func rectForHeader(inSection section: Int) -> CGRect
    // 获取某个组的尾标签的位置和大小
    open func rectForFooter(inSection section: Int) -> CGRect
    // 获取某一行的位置和大小
    open func rectForRow(at indexPath: IndexPath) -> CGRect
    
    // 点击某一个点, 判断是在哪一行上的信息.
    open func indexPathForRow(at point: CGPoint) -> IndexPath?
    // 获取单元格的信息
    open func indexPath(for cell: UITableViewCell) -> IndexPath?
    // 在某个区域里会返回多个单元格信息
    open func indexPathsForRows(in rect: CGRect) -> [IndexPath]?
    
    
    // 通过单元格路径得到单元格
    open func cellForRow(at indexPath: IndexPath) -> UITableViewCell?
    
    // 返回所有可见的单元格
    open var visibleCells: [UITableViewCell] { get }
    
    // 返回所有可见行的索引
    open var indexPathsForVisibleRows: [IndexPath]? { get }
    
    // 返回section头标签的视图
    open func headerView(forSection section: Int) -> UITableViewHeaderFooterView?
    
    // 返回section尾标签的视图
    open func footerView(forSection section: Int) -> UITableViewHeaderFooterView?
    
    // 滑动到指定索引位置
    open func scrollToRow(at indexPath: IndexPath, at scrollPosition: UITableView.ScrollPosition, animated: Bool)
    
    open func scrollToNearestSelectedRow(at scrollPosition: UITableView.ScrollPosition, animated: Bool)
    
    
    // Reloading and Updating
    
    // Allows multiple insert/delete/reload/move calls to be animated simultaneously. Nestable.
    @available(iOS 11.0, *)
    open func performBatchUpdates(_ updates: (() -> Void)?, completion: ((Bool) -> Void)? = nil)
    
    
    // 只添加或删除才会更新行数
    open func beginUpdates()
    // 添加或删除后会调用添加或删除方法时才会更新
    open func endUpdates()
    
    // 插入一个或多个组, 并使用动画
    open func insertSections(_ sections: IndexSet, with animation: UITableView.RowAnimation)
    // 删除一个或多个组, 并使用动画
    open func deleteSections(_ sections: IndexSet, with animation: UITableView.RowAnimation)
    
    // 移动某个组到目标组位置
    open func moveSection(_ section: Int, toSection newSection: Int)
    
    // 更新一个或多个组, 并使用动画
    open func reloadSections(_ sections: IndexSet, with animation: UITableView.RowAnimation)
    
    // 插入一个或多个单元格, 并使用动画
    open func insertRows(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation)
    // 删除一个或多个单元格, 并使用动画
    open func deleteRows(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation)
    
    // 移动个某个单元格到目标单元格位置
    open func moveRow(at indexPath: IndexPath, to newIndexPath: IndexPath)
    
    // 更新一个或多个单元格, 并使用动画
    open func reloadRows(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation)
    
    // Reconfigures any existing cells for the rows. Reconfiguring is more efficient than reloading a row, as it does not replace the
    // existing cell with a new cell. Prefer reconfiguring over reloading unless you actually need an entirely new cell for the row.
    @available(iOS 15.0, *)
    open func reconfigureRows(at indexPaths: [IndexPath])
    
    
    // Returns YES if the table view is in the middle of reordering, is displaying a drop target gap, or has drop placeholders. If possible, avoid calling -reloadData while there are uncommitted updates to avoid interfering with user-initiated interactions that have not yet completed.
    @available(iOS 11.0, *)
    open var hasUncommittedUpdates: Bool { get }
    
    
    // 从头重新加载所有内容. 重新显示可见行.
    // 注意, 这将导致删除所有现有的拖放占位符行.
    open func reloadData()
    
    
    // 刷新索引栏
    open func reloadSectionIndexTitles()
    
    
    // 编辑. 设置后, 行显示基于数据源查询的插入/删除/重新排序控件
    // 是否进入编辑状态, 默认是NO
    open var isEditing: Bool
    // 是否进入编辑状态, 带动画. 默认是NO
    open func setEditing(_ editing: Bool, animated: Bool)
    
    // 默认为YES. 在非编辑下, 行是否可以选中
    open var allowsSelection: Bool
    
    // 默认为NO. 控制某一行时, 是否可以编辑
    open var allowsSelectionDuringEditing: Bool
    
    // 默认为NO. 是否可以同时选择多个行
    open var allowsMultipleSelection: Bool
    
    //默认为NO. 在选择多行的情况下, 是否可以编辑
    open var allowsMultipleSelectionDuringEditing: Bool
    
    
    // Selection
    
    // 返回选择的一个单元格的索引
    open var indexPathForSelectedRow: IndexPath? { get }
    // 返回选择的所有的单元格的路径
    open var indexPathsForSelectedRows: [IndexPath]? { get }
    
    
    // 选中某个索引的单元格
    // 这些方法不会调用委托方法(-tableView:willSelectRowAtIndexPath:或tableView:didSelectRowAtIndexPath:),
    // 也不会发送通知
    open func selectRow(at indexPath: IndexPath?, animated: Bool, scrollPosition: UITableView.ScrollPosition)
    // 取消选中的单元格
    open func deselectRow(at indexPath: IndexPath, animated: Bool)
    
    
    // Appearance
    // 显示某个组索引列表在右边当行数达到这个值，默认是NSInteger的最大值
    open var sectionIndexMinimumDisplayRowCount: Int
    // 选择某个部分的某行改变这一行上文本的颜色
    open var sectionIndexColor: UIColor?
    
    @available(iOS 7.0, *)
    open var sectionIndexBackgroundColor: UIColor? // the background color of the section index while not being touched
    
    // 设置选中某个部分的背景颜色
    open var sectionIndexTrackingBackgroundColor: UIColor?
    
    // 设置单元格分隔线的样式
    open var separatorStyle: UITableViewCell.SeparatorStyle
    // 设置选中单元格分隔线的颜色
    open var separatorColor: UIColor?
    
    @available(iOS 8.0, *)
    @NSCopying open var separatorEffect: UIVisualEffect? // effect to apply to table separators
    
    
    @available(iOS 9.0, *)
    open var cellLayoutMarginsFollowReadableWidth: Bool // if cell layout margins are derived from the width of the readableContentGuide. default is NO.
    
    @available(iOS 11.0, *)
    open var insetsContentViewsToSafeArea: Bool // default value is YES
    
    // 设置组表的头标签视图
    open var tableHeaderView: UIView?
    // 设置组表的尾标签视图
    open var tableFooterView: UIView?
    
    // 获取重用队列里的单元格
    // 委托用来获取一个已经分配的单元格, 而不是分配一个新的单元格
    open func dequeueReusableCell(withIdentifier identifier: String) -> UITableViewCell?
    
    // 获取重用队列里的单元格
    // 更新的出队列方法保证返回一个单元格并正确调整其大小, 假定标识符已注册
    open func dequeueReusableCell(withIdentifier identifier: String, for indexPath: IndexPath) -> UITableViewCell
    
    // 获取重用队列里的 UITableViewHeaderFooterView
    // 具体获取的是HeaderView 还是FooterView 看 identifier
    open func dequeueReusableHeaderFooterView(withIdentifier identifier: String) -> UITableViewHeaderFooterView?
    
    
    // 注册UINib单元格
    open func register(_ nib: UINib?, forCellReuseIdentifier identifier: String)
    
    // 注册AnyClass单元格
    open func register(_ cellClass: AnyClass?, forCellReuseIdentifier identifier: String)
    
    
    // 注册UINib HeaderFooterView
    open func register(_ nib: UINib?, forHeaderFooterViewReuseIdentifier identifier: String)
    
    // 注册AnyClass HeaderFooterView
    open func register(_ aClass: AnyClass?, forHeaderFooterViewReuseIdentifier identifier: String)
    
    
    // Focus
    
    @available(iOS 9.0, *)
    open var remembersLastFocusedIndexPath: Bool // defaults to NO. If YES, when focusing on a table view the last focused index path is focused automatically. If the table view has never been focused, then the preferred focused index path is used.
    
    
    /// When enabled, the table view ensures that selection is automatically triggered when focus moves to a cell.
    /// Defaults to a system derived value based on platform and other properties of the table view.
    @available(iOS 14.0, *)
    open var selectionFollowsFocus: Bool
    
    
    /// Determines if the table view allows its cells to become focused.
    /// When tableView:canFocusRowAtIndexPath: is implemented, its return value takes precedence over this method.
    /// Defaults to a system derived value based on platform and other properties of the table view.
    @available(iOS 15.0, *)
    open var allowsFocus: Bool
    
    
    /// Determines if the table view allows its cells to become focused while editing.
    /// When tableView:canFocusRowAtIndexPath: is implemented, its return value takes precedence over this method.
    /// Defaults to a system derived value based on platform and other properties of the table view.
    @available(iOS 15.0, *)
    open var allowsFocusDuringEditing: Bool
    
    
    // Drag & Drop
    
    // You can force drags to be disabled for this table view by setting this to NO.
    // As of iOS 15, this is true for both iPhone and iPad by default. Prior to iOS 15, it defaulted to false on iPhone.
    @available(iOS 11.0, *)
    open var dragInteractionEnabled: Bool
    
    
    // YES if a drag session is currently active. A drag session begins after rows are "lifted" from the table view.
    @available(iOS 11.0, *)
    open var hasActiveDrag: Bool { get }
    
    
    // YES if table view is currently tracking a drop session.
    @available(iOS 11.0, *)
    open var hasActiveDrop: Bool { get }
}
